#include "pch.hpp"
#include "CssGrammar.hpp"

using namespace Engine;
using namespace Engine::Ui;




CssGrammar::CssGrammar()
	: CssGrammar::base_type(start)
{
	using namespace boost::phoenix;
	using namespace boost::spirit;

	using boost::spirit::qi::_val;
	using boost::spirit::qi::_1;
	using boost::spirit::qi::_2;
	using boost::spirit::qi::_3;
	using boost::spirit::qi::_4;

	using boost::spirit::ascii::alnum;
	using boost::spirit::ascii::alpha;
	using boost::spirit::lexeme;
	using boost::spirit::raw;
	using boost::spirit::ascii::char_;

	//
	// Don't ever touch those rules again
	//
	class_state   %= stateTypes >> eps; //< Dummy character
	identifier     = eps[_val = ""] >> ((char_('_', '_') | char_('a', 'z') | char_('A', 'Z'))[_val += _1] >> *(char_('_', '_') | char_('a', 'z') | char_('A', 'Z') | char_('0', '9'))[_val += _1]) | char_('*')[_val = '*'];
	parent        %= -classTypes >> ('.' > identifier) >> -(':' > class_state);
	class_head    %= +parent;
	quoted_string %= lexeme[lit('"') >> +(char_ -'"') >> lit('"')];
	string        %= +(char_ - (char_(';') | '}' | ' '));
	attributes     = *(attributeTypes > ':' > (string | quoted_string) > ';')[insert(_val, _1, _2)];
	classs        %= class_head > lit('{') >> -attributes > lit('}');
	start         %= +classs;

	class_state.name("class-state");
	identifier.name("class-identifier");
	parent.name("class-parent");
	class_head.name("class-head");
	quoted_string.name("quoted string");
	string.name("string");
	attributes.name("attributes");
	classs.name("class");
	start.name("classes");

	boost::spirit::qi::on_error<boost::spirit::qi::fail>
		(
		start
		, /*throw_(
		  boost_ext::exception(boost_ext::format("Expecting %1% near '%2%'")
		  % _4
		  % boost::phoenix::construct<std::string>(_3, _2))
		  << debug_info()
		  )*/
		  std::cerr
		  << val("Expecting ")
		  << _4
		  << val(" near '")
		  << boost::phoenix::construct<std::string>(_3, _2)
		  << val("'")
		  );
}